﻿using TMPro.EditorUtilities;

namespace Raven
{
    public enum GoalStatus
    {
        active,
        inactive,
        completed,
        failed
    }

    public abstract class Goal<entity_type>
    {
        //an enumerated type specifying the type of goal
        protected GoalType _type;

        //a pointer to the entity that owns this goal
        protected entity_type _owner;

        //an enumerated value indicating the goal's status (active, inactive,
        //completed, failed)
        protected GoalStatus _status;

        /* the following methods were created to factor out some of the commonality
        in the implementations of the Process method() */

        //if m_iStatus = inactive this method sets it to active and calls Activate()
        protected void ActivateIfInactive()
        {
            if (isInactive())
            {
                Activate();   
            }

        }

        //if m_iStatus is failed this method sets it to inactive so that the goal
        //will be reactivated (and therefore re-planned) on the next update-step.
        protected void ReactivateIfFailed()
        {
            if (hasFailed())
            {
                _status = GoalStatus.inactive;
            }
        }

        public Goal(entity_type owner, GoalType type)
        {
            _owner = owner;
            _type = type;
            _status = GoalStatus.inactive;
        }

        //logic to run when the goal is activated.
        public abstract void Activate();

        //logic to run each update-step
        public abstract GoalStatus Process();

        //logic to run when the goal is satisfied. (typically used to switch
        //off any active steering behaviors)
        public abstract void Terminate();

        //goals can handle messages. Many don't though, so this defines a default
        //behavior
        public virtual bool HandleMessage(Telegram msg)
        {
            return false;
        }

        public bool isComplete()
        {
            return _status == GoalStatus.completed;
        }

        public bool isActive()
        {
            return _status == GoalStatus.active;
        }

        public bool isInactive()
        {
            return _status == GoalStatus.inactive;
        }

        public bool hasFailed()
        {
            return _status == GoalStatus.failed;
        }

        public GoalType GetGoalType()
        {
            return _type;
        }
    }
}